unit DIrr.GPU;

{$I DIrr.inc}

interface

uses
  DIrr.Base, DIrr.Types, DIrr.Structs, DIrr.IO, DIrr.RenderServices;

type
  //! Interface making it possible to set constants for gpu programs every frame.
  (** Implement this interface in an own class and pass a pointer to it to one of
  the methods in IGPUProgrammingServices when creating a shader. The
  OnSetConstants method will be called every frame now. *)
  TShaderConstantSetCallBack = class(TNamedObject)
  public
    //! Called to let the callBack know the used material (optional method)
    (**
     \code
    class MyCallBack : public IShaderConstantSetCallBack
    {
      const video::SMaterial *UsedMaterial;

      OnSetMaterial(const video::SMaterial& material)
      {
        UsedMaterial=&material;
      }

      OnSetConstants(IMaterialRendererServices* services, s32 userData)
      {
        services->setVertexShaderConstant("myColor", reinterpret_cast<f32*>(&UsedMaterial->color), 4);
      }
    }
    \endcode
    *)
    procedure OnSetMaterial(const Material: SMaterial); virtual; stdcall;

    //! Called by the engine when the vertex and/or pixel shader constants for an material renderer should be set.
    (**
    Implement the IShaderConstantSetCallBack in an own class and implement your own
    OnSetConstants method using the given IMaterialRendererServices interface.
    Pass a pointer to this class to one of the methods in IGPUProgrammingServices
    when creating a shader. The OnSetConstants method will now be called every time
    before geometry is being drawn using your shader material. A sample implementation
    would look like this:
    \code
    virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
    {
      video::IVideoDriver* driver = services->getVideoDriver();

      // set clip matrix at register 4
      core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION));
      worldViewProj *= driver->getTransform(video::ETS_VIEW);
      worldViewProj *= driver->getTransform(video::ETS_WORLD);
      services->setVertexShaderConstant(&worldViewProj.M[0], 4, 4);
      // for high level shading languages, this would be another solution:
      //services->setVertexShaderConstant("mWorldViewProj", worldViewProj.M, 16);

      // set some light color at register 9
      video::SColorf col(0.0f,1.0f,1.0f,0.0f);
      services->setVertexShaderConstant(reinterpret_cast<const f32*>(&col), 9, 1);
      // for high level shading languages, this would be another solution:
      //services->setVertexShaderConstant("myColor", reinterpret_cast<f32*>(&col), 4);
    }
    \endcode
    \param services: Pointer to an interface providing methods to set the constants for the shader.
    \param userData: Userdata int which can be specified when creating the shader.
    *)
    procedure OnSetConstants(Services: TRendererServices; UserData: S32); virtual; stdcall; abstract;
  end;

type
  TGPUProgrammingServices = class
  protected
    procedure _CPP_Destory; virtual; stdcall; abstract;
  public
    //! convenience function for use without geometry shaders
    function AddHighLevelShaderMaterial(
      VertexShaderProgram: AnsiString;
      const VertexShaderEntryPointName: AnsiString = 'main';
      vsCompileTarget: E_VERTEX_SHADER_TYPE = EVST_VS_1_1;
      PixelShaderProgram: PAnsiChar = nil;
      const PixelShaderEntryPointName: AnsiString = 'main';
      psCompileTarget: E_PIXEL_SHADER_TYPE = EPST_PS_1_1;
      Callback: TShaderConstantSetCallBack = nil;
      BaseMaterial: E_MATERIAL_TYPE = EMT_SOLID;
      UserData: s32 = 0;
      ShadingLang: E_GPU_SHADING_LANGUAGE = EGSL_DEFAULT): s32; overload;

    //! convenience function for use with many defaults, without geometry shader
    (** All shader names are set to "main" and compile targets are shader
    type 1.1.*)
    function AddHighLevelShaderMaterial(
      VertexShaderProgram: AnsiString;
      PixelShaderProgram: AnsiString = '';
      Callback: TShaderConstantSetCallBack = nil;
      BaseMaterial: E_MATERIAL_TYPE = EMT_SOLID;
      UserData: s32 = 0): s32; overload;

    //! convenience function for use with many defaults, with geometry shader
    (** All shader names are set to "main" and compile targets are shader
    type 1.1 and geometry shader 4.0. *)
    function AddHighLevelShaderMaterial(
      VertexShaderProgram: AnsiString;
      PixelShaderProgram: AnsiString = '';
      GeometryShaderProgram: AnsiString = '';
      InType: E_PRIMITIVE_TYPE = EPT_TRIANGLES;
      OutType: E_PRIMITIVE_TYPE = EPT_TRIANGLE_STRIP;
      VerticesOut: U32 = 0;
      Callback: TShaderConstantSetCallBack = nil;
      BaseMaterial: E_MATERIAL_TYPE = EMT_SOLID;
      UserData: s32 = 0): S32; overload;

    //! convenience function for use with many defaults, without geometry shader
    (** All shader names are set to "main" and compile targets are shader
    type 1.1.*)
    function AddHighLevelShaderMaterialFromFiles(
      VertexShaderProgramFileName: AnsiString;
      PixelShaderProgramFileName: AnsiString = '';
      Callback: TShaderConstantSetCallBack = nil;
      BaseMaterial: E_MATERIAL_TYPE = EMT_SOLID;
      UserData: S32 = 0): S32; overload;

    //! convenience function for use with many defaults, with geometry shader
    (** All shader names are set to "main" and compile targets are shader
    type 1.1 and geometry shader 4.0.*)
    function AddHighLevelShaderMaterialFromFiles(
      VertexShaderProgramFileName: AnsiString;
      PixelShaderProgramFileName: AnsiString = '';
      GeometryShaderProgramFileName: AnsiString = '';
      InType: E_PRIMITIVE_TYPE = EPT_TRIANGLES;
      OutType: E_PRIMITIVE_TYPE = EPT_TRIANGLE_STRIP;
      VerticesOut: U32 = 0;
      Callback: TShaderConstantSetCallBack = nil;
      BaseMaterial: E_MATERIAL_TYPE = EMT_SOLID;
      UserData: S32 = 0): S32; overload;

    //! convenience function for use without geometry shaders
    function AddHighLevelShaderMaterialFromFiles(
      VertexShaderProgram: TReadFile;
      VertexShaderEntryPointName: AnsiString = 'main';
      vsCompileTarget: E_VERTEX_SHADER_TYPE = EVST_VS_1_1;
      pixelShaderProgram: TReadFile = nil;
      PixelShaderEntryPointName: AnsiString = 'main';
      psCompileTarget: E_PIXEL_SHADER_TYPE = EPST_PS_1_1;
      Callback: TShaderConstantSetCallBack = nil;
      BaseMaterial: E_MATERIAL_TYPE = EMT_SOLID;
      UserData: S32 = 0;
      ShadingLang: E_GPU_SHADING_LANGUAGE = EGSL_DEFAULT): S32; overload;

    function AddHighLevelShaderMaterialFromFiles(
      VertexShaderProgramFileName: AnsiString;
      VertexShaderEntryPointName: AnsiString = 'main';
      vsCompileTarget: E_VERTEX_SHADER_TYPE = EVST_VS_1_1;
      PixelShaderProgramFileName: AnsiString = '';
      PixelShaderEntryPointName: AnsiString = 'main';
      psCompileTarget: E_PIXEL_SHADER_TYPE = EPST_PS_1_1;
      Callback: TShaderConstantSetCallBack = nil;
      BaseMaterial: E_MATERIAL_TYPE = EMT_SOLID;
      UserData: S32 = 0;
      ShadingLang: E_GPU_SHADING_LANGUAGE = EGSL_DEFAULT): S32; overload;

  public
    //! Adds a new high-level shading material renderer to the VideoDriver.
    (** Currently only HLSL/D3D9 and GLSL/OpenGL are supported.
    \param vertexShaderProgram String containing the source of the vertex
    shader program. This can be 0 if no vertex program shall be used.
    \param vertexShaderEntryPointName Name of the entry function of the
    vertexShaderProgram (p.e. "main")
    \param vsCompileTarget Vertex shader version the high level shader
    shall be compiled to.
    \param pixelShaderProgram String containing the source of the pixel
    shader program. This can be 0 if no pixel shader shall be used.
    \param pixelShaderEntryPointName Entry name of the function of the
    pixelShaderProgram (p.e. "main")
    \param psCompileTarget Pixel shader version the high level shader
    shall be compiled to.
    \param geometryShaderProgram String containing the source of the
    geometry shader program. This can be 0 if no geometry shader shall be
    used.
    \param geometryShaderEntryPointName Entry name of the function of the
    geometryShaderProgram (p.e. "main")
    \param gsCompileTarget Geometry shader version the high level shader
    shall be compiled to.
    \param inType Type of vertices passed to geometry shader
    \param outType Type of vertices created by geometry shader
    \param verticesOut Maximal number of vertices created by geometry
    shader. If 0, maximal number supported is assumed.
    \param callback Pointer to an implementation of
    IShaderConstantSetCallBack in which you can set the needed vertex,
    pixel, and geometry shader program constants. Set this to 0 if you
    don't need this.
    \param baseMaterial Base material which renderstates will be used to
    shade the material.
    \param userData a user data int. This int can be set to any value and
    will be set as parameter in the callback method when calling
    OnSetConstants(). In this way it is easily possible to use the same
    callback method for multiple materials and distinguish between them
    during the call.
    \param shaderLang a type of shading language used in current shader.
    \return Number of the material type which can be set in
    SMaterial::MaterialType to use the renderer. -1 is returned if an error
    occured, e.g. if a shader program could not be compiled or a compile
    target is not reachable. The error strings are then printed to the
    error log and can be catched with a custom event receiver. *)
    function AddHighLevelShaderMaterial(
      const VertexShaderProgram: AnsiString;
      const VertexShaderEntryPointName: AnsiString;
      vsCompileTarget: E_VERTEX_SHADER_TYPE;
      const pixelShaderProgram: AnsiString;
      const pixelShaderEntryPointName: AnsiString;
      psCompileTarget: E_PIXEL_SHADER_TYPE;
      const GeometryShaderProgram: PAnsiChar;
      const GeometryShaderEntryPointName: AnsiString = 'main';
      gsCompileTarget: E_GEOMETRY_SHADER_TYPE = EGST_GS_4_0;
      InType: E_PRIMITIVE_TYPE = EPT_TRIANGLES;
      OutType: E_PRIMITIVE_TYPE = EPT_TRIANGLE_STRIP;
      VerticesOut: U32 = 0;
      Callback: TShaderConstantSetCallBack = nil;
      BaseMaterial: E_MATERIAL_TYPE = EMT_SOLID;
      UserData: S32 = 0;
      ShadingLang: E_GPU_SHADING_LANGUAGE = EGSL_DEFAULT): S32; overload; virtual; stdcall; abstract;

    //! Like IGPUProgrammingServices::addShaderMaterial(), but loads from files.
    (** \param vertexShaderProgram Text file handle containing the source
    of the vertex shader program. Set to 0 if no vertex shader shall be
    created.
    \param vertexShaderEntryPointName Name of the entry function of the
    vertexShaderProgram
    \param vsCompileTarget Vertex shader version the high level shader
    shall be compiled to.
    \param pixelShaderProgram Text file handle containing the source of
    the pixel shader program. Set to 0 if no pixel shader shall be created.
    \param pixelShaderEntryPointName Entry name of the function of the
    pixelShaderProgram (p.e. "main")
    \param psCompileTarget Pixel shader version the high level shader
    shall be compiled to.
    \param geometryShaderProgram Text file handle containing the source of
    the geometry shader program. Set to 0 if no geometry shader shall be
    created.
    \param geometryShaderEntryPointName Entry name of the function of the
    geometryShaderProgram (p.e. "main")
    \param gsCompileTarget Geometry shader version the high level shader
    shall be compiled to.
    \param inType Type of vertices passed to geometry shader
    \param outType Type of vertices created by geometry shader
    \param verticesOut Maximal number of vertices created by geometry
    shader. If 0, maximal number supported is assumed.
    \param callback Pointer to an implementation of
    IShaderConstantSetCallBack in which you can set the needed vertex and
    pixel shader program constants. Set this to 0 if you don't need this.
    \param baseMaterial Base material which renderstates will be used to
    shade the material.
    \param userData a user data int. This int can be set to any value and
    will be set as parameter in the callback method when calling
    OnSetConstants(). In this way it is easily possible to use the same
    callback method for multiple materials and distinguish between them
    during the call.
    \param shaderLang a type of shading language used in current shader.
    \return Number of the material type which can be set in
    SMaterial::MaterialType to use the renderer. -1 is returned if an
    error occured, e.g. if a shader program could not be compiled or a
    compile target is not reachable. The error strings are then printed to
    the error log and can be catched with a custom event receiver. *)
    function AddHighLevelShaderMaterialFromFiles(
      VertexShaderProgram: TReadFile;
      const VertexShaderEntryPointName: AnsiString;
      vsCompileTarget: E_VERTEX_SHADER_TYPE;
      pixelShaderProgram: TReadFile;
      const PixelShaderEntryPointName: AnsiString;
      psCompileTarget: E_PIXEL_SHADER_TYPE;
      GeometryShaderProgram: TReadFile;
      const GeometryShaderEntryPointName: AnsiString = 'main';
      gsCompileTarget: E_GEOMETRY_SHADER_TYPE = EGST_GS_4_0;
      InType: E_PRIMITIVE_TYPE = EPT_TRIANGLES;
      OutType: E_PRIMITIVE_TYPE = EPT_TRIANGLE_STRIP;
      VerticesOut: U32 = 0;
      Callback: TShaderConstantSetCallBack = nil;
      BaseMaterial: E_MATERIAL_TYPE = EMT_SOLID;
      UserData: S32 = 0;
      ShadingLang: E_GPU_SHADING_LANGUAGE = EGSL_DEFAULT): S32; overload; virtual; stdcall; abstract;

    //! Like IGPUProgrammingServices::addShaderMaterial(), but loads from files.
    (** \param vertexShaderProgramFileName Text file containing the source
    of the vertex shader program. Set to empty string if no vertex shader
    shall be created.
    \param vertexShaderEntryPointName Name of the entry function of the
    vertexShaderProgram  (p.e. "main")
    \param vsCompileTarget Vertex shader version the high level shader
    shall be compiled to.
    \param pixelShaderProgramFileName Text file containing the source of
    the pixel shader program. Set to empty string if no pixel shader shall
    be created.
    \param pixelShaderEntryPointName Entry name of the function of the
    pixelShaderProgram (p.e. "main")
    \param psCompileTarget Pixel shader version the high level shader
    shall be compiled to.
    \param geometryShaderProgramFileName Name of the source of
    the geometry shader program. Set to empty string if no geometry shader
    shall be created.
    \param geometryShaderEntryPointName Entry name of the function of the
    geometryShaderProgram (p.e. "main")
    \param gsCompileTarget Geometry shader version the high level shader
    shall be compiled to.
    \param inType Type of vertices passed to geometry shader
    \param outType Type of vertices created by geometry shader
    \param verticesOut Maximal number of vertices created by geometry
    shader. If 0, maximal number supported is assumed.
    \param callback Pointer to an implementation of
    IShaderConstantSetCallBack in which you can set the needed vertex,
    pixel, and geometry shader program constants. Set this to 0 if you
    don't need this.
    \param baseMaterial Base material which renderstates will be used to
    shade the material.
    \param userData a user data int. This int can be set to any value and
    will be set as parameter in the callback method when calling
    OnSetConstants(). In this way it is easily possible to use the same
    callback method for multiple materials and distinguish between them
    during the call.
    \param shaderLang a type of shading language used in current shader.
    \return Number of the material type which can be set in
    SMaterial::MaterialType to use the renderer. -1 is returned if an error
    occured, e.g. if a shader program could not be compiled or a compile
    target is not reachable. The error strings are then printed to the
    error log and can be catched with a custom event receiver. *)
    function AddHighLevelShaderMaterialFromFiles(
      const VertexShaderProgramFileName: TIrrAnsiString;
      const VertexShaderEntryPointName: AnsiString;
      vsCompileTarget: E_VERTEX_SHADER_TYPE;
      const PixelShaderProgramFileName: TIrrAnsiString;
      const PixelShaderEntryPointName: AnsiString;
      psCompileTarget: E_PIXEL_SHADER_TYPE;
      const GeometryShaderProgramFileName: TIrrAnsiString;
      const GeometryShaderEntryPointName: AnsiString = 'main';
      gsCompileTarget: E_GEOMETRY_SHADER_TYPE = EGST_GS_4_0;
      InType: E_PRIMITIVE_TYPE = EPT_TRIANGLES;
      OutType: E_PRIMITIVE_TYPE = EPT_TRIANGLE_STRIP;
      VerticesOut: U32 = 0;
      Callback: TShaderConstantSetCallBack = nil;
      BaseMaterial: E_MATERIAL_TYPE = EMT_SOLID;
      UserData: S32 = 0;
      ShadingLang: E_GPU_SHADING_LANGUAGE = EGSL_DEFAULT): S32; overload; virtual; stdcall; abstract;

    //! Like IGPUProgrammingServices::addShaderMaterial(), but loads from files.
    (** \param vertexShaderProgram Text file containing the source of the
    vertex shader program. Set to 0 if no shader shall be created.
    \param pixelShaderProgram Text file containing the source of the pixel
    shader program. Set to 0 if no shader shall be created.
    \param callback Pointer to an IShaderConstantSetCallback object to
    which the OnSetConstants function is called.
    \param baseMaterial baseMaterial
    \param userData a user data int. This int can be set to any value and
    will be set as parameter in the callback method when calling
    OnSetConstants(). In this way it is easily possible to use the same
    callback method for multiple materials and distinguish between them
    during the call.
    \return Returns the number of the material type which can be set in
    SMaterial::MaterialType to use the renderer. -1 is returned if an
    error occured. -1 is returned for example if a vertex or pixel shader
    program could not be compiled, the error strings are then printed out
    into the error log, and can be catched with a custom event receiver. *)
    function AddShaderMaterialFromFiles(VertexShaderProgram: TReadFile;
      PixelShaderProgram: TReadFile;
      Callback: TShaderConstantSetCallBack = nil;
      BaseMaterial: E_MATERIAL_TYPE = EMT_SOLID;
      UserData: S32 = 0): S32; overload; virtual; stdcall; abstract;

    //! Adds a new ASM shader material renderer to the VideoDriver
    (** Note that it is a good idea to call IVideoDriver::queryFeature() in
    advance to check if the IVideoDriver supports the vertex and/or pixel
    shader version your are using.

    The material is added to the VideoDriver like with
    IVideoDriver::addMaterialRenderer() and can be used like it had been
    added with that method.
    \param vertexShaderProgram String containing the source of the vertex
    shader program. This can be 0 if no vertex program shall be used.

    For DX8 programs, the will always input registers look like this: v0:
    position, v1: normal, v2: color, v3: texture cooridnates, v4: texture
    coordinates 2 if available.

    For DX9 programs, you can manually set the registers using the dcl_
    statements.
    \param pixelShaderProgram String containing the source of the pixel
    shader program. This can be 0 if you don't want to use a pixel shader.
    \param callback Pointer to an implementation of
    IShaderConstantSetCallBack in which you can set the needed vertex and
    pixel shader program constants. Set this to 0 if you don't need this.
    \param baseMaterial Base material which renderstates will be used to
    shade the material.
    \param userData a user data int. This int can be set to any value and
    will be set as parameter in the callback method when calling
    OnSetConstants(). In this way it is easily possible to use the same
    callback method for multiple materials and distinguish between them
    during the call.
    \return Returns the number of the material type which can be set in
    SMaterial::MaterialType to use the renderer. -1 is returned if an
    error occured. -1 is returned for example if a vertex or pixel shader
    program could not be compiled, the error strings are then printed out
    into the error log, and can be catched with a custom event receiver. *)
    function AddShaderMaterial(const VertexShaderProgram: PAnsiChar = nil;
      const PixelShaderProgram: PAnsiChar = nil;
      Callback: TShaderConstantSetCallBack = nil;
      BaseMaterial: E_MATERIAL_TYPE = EMT_SOLID;
      UserData: S32 = 0): S32; overload; virtual; stdcall; abstract;


    //! Like IGPUProgrammingServices::addShaderMaterial(), but loads from files.
    (** \param vertexShaderProgramFileName Text file name containing the
    source of the vertex shader program. Set to 0 if no shader shall be
    created.
    \param pixelShaderProgramFileName Text file name containing the source
    of the pixel shader program. Set to 0 if no shader shall be created.
    \param callback Pointer to an IShaderConstantSetCallback object on
    which the OnSetConstants function is called.
    \param baseMaterial baseMaterial
    \param userData a user data int. This int can be set to any value and
    will be set as parameter in the callback method when calling
    OnSetConstants(). In this way it is easily possible to use the same
    callback method for multiple materials and distinguish between them
    during the call.
    \return Returns the number of the material type which can be set in
    SMaterial::MaterialType to use the renderer. -1 is returned if an
    error occured. -1 is returned for example if a vertex or pixel shader
    program could not be compiled, the error strings are then printed out
    into the error log, and can be catched with a custom event receiver. *)
    function AddShaderMaterialFromFiles(const VertexShaderProgramFileName: TIrrAnsiString;
      const PixelShaderProgramFileName: TIrrAnsiString;
      Callback: TShaderConstantSetCallBack = nil;
      BaseMaterial: E_MATERIAL_TYPE = EMT_SOLID;
      UserData: S32 = 0): S32; overload; virtual; stdcall; abstract;
  end;

implementation

{ TShaderConstantSetCallBack }

procedure TShaderConstantSetCallBack.OnSetMaterial(const Material: SMaterial);
begin

end;

{ TGPUProgrammingServices }

function TGPUProgrammingServices.AddHighLevelShaderMaterialFromFiles(
  VertexShaderProgramFileName, VertexShaderEntryPointName: AnsiString;
  vsCompileTarget: E_VERTEX_SHADER_TYPE; PixelShaderProgramFileName,
  PixelShaderEntryPointName: AnsiString; psCompileTarget: E_PIXEL_SHADER_TYPE;
  Callback: TShaderConstantSetCallBack; BaseMaterial: E_MATERIAL_TYPE;
  UserData: S32; ShadingLang: E_GPU_SHADING_LANGUAGE): S32;
begin
  Result := AddHighLevelShaderMaterialFromFiles(
              VertexShaderProgramFileName,
              VertexShaderEntryPointName,
              vsCompileTarget,
              PixelShaderProgramFileName,
              PixelShaderEntryPointName,
              psCompileTarget,
              nil,
              'main',
              EGST_GS_4_0,
              EPT_TRIANGLES,
              EPT_TRIANGLE_STRIP,
              0,
              Callback,
              BaseMaterial,
              UserData,
              ShadingLang
            );
end;

function TGPUProgrammingServices.AddHighLevelShaderMaterial(
  VertexShaderProgram: AnsiString; const VertexShaderEntryPointName: AnsiString;
  vsCompileTarget: E_VERTEX_SHADER_TYPE; PixelShaderProgram: PAnsiChar;
  const PixelShaderEntryPointName: AnsiString;
  psCompileTarget: E_PIXEL_SHADER_TYPE; Callback: TShaderConstantSetCallBack;
  BaseMaterial: E_MATERIAL_TYPE; UserData: s32;
  ShadingLang: E_GPU_SHADING_LANGUAGE): s32;
begin
  Result := AddHighLevelShaderMaterial(
              VertexShaderProgram,
              VertexShaderEntryPointName,
              vsCompileTarget,
              PixelShaderProgram,
              PixelShaderEntryPointName,
              psCompileTarget,
              nil,
              'main',
              EGST_GS_4_0,
              EPT_TRIANGLES,
              EPT_TRIANGLE_STRIP,
              0,
              Callback,
              BaseMaterial,
              UserData,
              ShadingLang
            );
end;

function TGPUProgrammingServices.AddHighLevelShaderMaterial(VertexShaderProgram,
  PixelShaderProgram: AnsiString; Callback: TShaderConstantSetCallBack;
  BaseMaterial: E_MATERIAL_TYPE; UserData: s32): s32;
begin
  Result := AddHighLevelShaderMaterial(
              VertexShaderProgram,
              'main',
              EVST_VS_1_1,
              PixelShaderProgram,
              'main',
              EPST_PS_1_1,
              nil,
              'main',
              EGST_GS_4_0,
              EPT_TRIANGLES,
              EPT_TRIANGLE_STRIP,
              0,
              Callback,
              BaseMaterial,
              UserData
            );
end;

function TGPUProgrammingServices.AddHighLevelShaderMaterial(VertexShaderProgram,
  PixelShaderProgram, GeometryShaderProgram: AnsiString; InType,
  OutType: E_PRIMITIVE_TYPE; VerticesOut: U32;
  Callback: TShaderConstantSetCallBack; BaseMaterial: E_MATERIAL_TYPE;
  UserData: s32): S32;
begin
  Result := AddHighLevelShaderMaterial(
              VertexShaderProgram,
              'main',
              EVST_VS_1_1,
              PixelShaderProgram,
              'main',
              EPST_PS_1_1,
              PAnsiChar(GeometryShaderProgram),
              'main',
              EGST_GS_4_0,
              InType,
              OutType,
              VerticesOut,
              Callback,
              BaseMaterial,
              UserData
            );
end;

function TGPUProgrammingServices.AddHighLevelShaderMaterialFromFiles(
  VertexShaderProgramFileName, PixelShaderProgramFileName: AnsiString;
  Callback: TShaderConstantSetCallBack; BaseMaterial: E_MATERIAL_TYPE;
  UserData: S32): S32;
begin
  Result := AddHighLevelShaderMaterialFromFiles(
              VertexShaderProgramFileName,
              'main',
              EVST_VS_1_1,
              PixelShaderProgramFileName,
              'main',
              EPST_PS_1_1,
              '',
              'main',
              EGST_GS_4_0,
              EPT_TRIANGLES,
              EPT_TRIANGLE_STRIP,
              0,
              Callback,
              BaseMaterial,
              UserData
            );
end;

function TGPUProgrammingServices.AddHighLevelShaderMaterialFromFiles(
  VertexShaderProgramFileName, PixelShaderProgramFileName,
  GeometryShaderProgramFileName: AnsiString; InType, OutType: E_PRIMITIVE_TYPE;
  VerticesOut: U32; Callback: TShaderConstantSetCallBack;
  BaseMaterial: E_MATERIAL_TYPE; UserData: S32): S32;
begin
  Result := AddHighLevelShaderMaterialFromFiles(
              VertexShaderProgramFileName,
              'main',
              EVST_VS_1_1,
              PixelShaderProgramFileName,
              'main',
              EPST_PS_1_1,
              GeometryShaderProgramFileName,
              'main',
              EGST_GS_4_0,
              InType,
              OutType,
              VerticesOut,
              Callback,
              BaseMaterial,
              UserData
            );
end;

function TGPUProgrammingServices.AddHighLevelShaderMaterialFromFiles(
  VertexShaderProgram: TReadFile; VertexShaderEntryPointName: AnsiString;
  vsCompileTarget: E_VERTEX_SHADER_TYPE; PixelShaderProgram: TReadFile;
  PixelShaderEntryPointName: AnsiString; psCompileTarget: E_PIXEL_SHADER_TYPE;
  Callback: TShaderConstantSetCallBack; BaseMaterial: E_MATERIAL_TYPE;
  UserData: S32; ShadingLang: E_GPU_SHADING_LANGUAGE): S32;
begin
  Result := AddHighLevelShaderMaterialFromFiles(
              VertexShaderProgram,
              VertexShaderEntryPointName,
              vsCompileTarget,
              PixelShaderProgram,
              PixelShaderEntryPointName,
              psCompileTarget,
              nil,
              'main',
              EGST_GS_4_0,
              EPT_TRIANGLES,
              EPT_TRIANGLE_STRIP,
              0,
              Callback,
              BaseMaterial,
              UserData
            );
end;

end.
